<template>
  <div class="commission">
    <div class="detail">
      <dt-header :title="title" :line-number="3" ref="header">
        <Button type="error" v-if="info.status == 'NO_SETTLEMENT'" @click="onSendback">退回请佣单</Button>
        <Button
          type="error"
          v-if="
            info.status == 'SETTLED' &&
            info.invoicingStatus == 'NO_INVOICE' &&
            info.settlementStatus == 'NO_WRITE_OFF'
          "
          @click="onCancellation">
          作废
        </Button>
      </dt-header>
    </div>

    <div class="handles">
      <div>
        <p v-if="info.settlementType === 'STANDARD'">
          本次结算总销总计：{{ $dt.tool.formatterMoney(settlementTotalSale) }}元
        </p>
        <p>实际结算佣金总计：{{ $dt.tool.formatterMoney(realCommission) }}元</p>
        <p @click="onAdjust">
          调整佣金：
          <span>{{ $dt.tool.formatterMoney(adjustCommission) }}元</span>
        </p>
      </div>
      <ButtonGroup>
        <Button type="primary" @click="onAdjust">佣金调整</Button>
        <Button
          type="primary"
          @click="onRelation"
          v-if="
            info.settlementType === 'STANDARD' ||
            info.settlementType === 'DEPOSIT' ||
            info.settlementType === 'STANDARD_AND_DEPOSIT'
          ">
          关系户扣减
        </Button>
        <Button
          type="primary"
          @click="onRate"
          v-if="
            info.settlementType === 'STANDARD' ||
            info.settlementType === 'DEPOSIT' ||
            info.settlementType === 'STANDARD_AND_DEPOSIT'
          ">
          费率调整
        </Button>
        <Button type="primary" @click="onUpload">数据导入</Button>
        <Button type="primary" @click="onDownload">导出Excel</Button>
        <Button @click="onReset">重置</Button>
        <Button
          @click="onSave"
          v-if="
            info.settlementType === 'STANDARD' ||
            info.settlementType === 'DEPOSIT' ||
            info.settlementType === 'STANDARD_AND_DEPOSIT'
          ">
          暂存
        </Button>
        <Button type="primary" @click="onSubmit">确认提交</Button>
      </ButtonGroup>
    </div>

    <dt-grid ref="table" :list="filterList" :select="select" @filter="onFilter" />

    <dt-loading :loading="loading" />
    <sendback-modal ref="sendback" />
    <commission-adjust ref="adjust" />
    <relation-deduction ref="relation" />
    <rate-modal ref="rate" />
    <upload-modal ref="upload" />
    <submit-modal ref="submit" @success="getDetail" />
  </div>
</template>

<script>
  import Column from './opt/settlementColumn.js'
  import calcFun from './opt/calc.js'
  import detailOpt from './opt/detail.js'

  import sendbackModal from './components/sendback-modal.vue'
  import commissionAdjust from './components/commission-adjust.vue'
  import relationDeduction from './components/relation-deduction.vue'
  import rateModal from './components/rate-modal.vue'
  import uploadModal from './components/upload-modal.vue'
  import submitModal from './components/submit-modal.vue'

  import settlementMgr from '@/biz/commission/settlement.js'

  export default {
    components: {
      sendbackModal,
      commissionAdjust,
      relationDeduction,
      rateModal,
      uploadModal,
      submitModal
    },
    data() {
      return {
        title: '',
        info: {},
        list: [],
        filterList: [],
        adjustCommission: '0',
        loading: false,
        selected: [],
        select: {
          one: (selection, row) => {
            this.selected = selection
          },
          all: (selection) => {
            this.selected = selection
          }
        }
      }
    },
    mounted() {
      this.$refs.header.init(detailOpt.options(this), this.info)
      this.getDetail()
    },
    computed: {
      // 实际结算佣金总计 = 表格中「本次可结代理费」合计 + 调整佣金
      realCommission() {
        let sum = this.list.reduce((num, { actualAgentCost }) => {
          return num + Number(actualAgentCost)
        }, 0)
        return calcFun.dealPrecision(sum + Number(this.adjustCommission))
      },
      settlementTotalSale() {
        let sum = this.list.reduce((num, { settlementAmount }) => {
          return num + Number(settlementAmount)
        }, 0)
        return calcFun.dealPrecision(sum)
      }
    },
    methods: {
      getDetail() {
        this.loading = true
        settlementMgr.detail(this.$route.query.commissionId).then((res) => {
          this.title = `${res.housesName} — ${res.commissionName} (${res.commissionMonth} ${this.$dt
            .dictInfo()
            .__value('settlementType', res.settlementType)})`
          this.info = res
          this.$refs.header.init(detailOpt.options(this), this.info)
          this.adjustCommission = this.info.adjustAmount || 0
          this.$refs.table.init(this, new Column(res.settlementType, this.info, this.onBlur, true))
          this.list = res.settlementDetails || []
          this.filterList = res.settlementDetails || []
          this.loading = false
        })
      },
      onFilter(data) {
        this.filterList = settlementMgr.filterData(this.list, data)
      },
      // 退回
      onSendback() {
        this.$refs.sendback.show()
      },
      // 作废
      onCancellation() {
        this.$Modal.confirm({
          title: '是否作废该佣金结算单？',
          content: '作废后，该佣金单内数据全部失效，数据回滚',
          onOk: () => {
            settlementMgr.cancellation(this.$route.query.commissionId).then(() => {
              this.$Message.success('该佣金结算单已作废')
              this.$store.commit('deleteroutefun', this.$route.meta.title)
              this.$router.go(-1)
            })
          }
        })
      },
      // 佣金调整
      onAdjust() {
        this.$refs.adjust.show(true)
      },
      // 关系户扣减
      onRelation() {
        this.$refs.relation.show(this.info)
      },
      relationUpdate(type, amount) {
        this.filterList = this.filterList.map((item) => {
          this.info.reduceType = type
          this.info.reduceAmount = amount
          if (item.isAssociates) {
            // 更新关联数据
            let data = calcFun.onAssociates(this.info, item, type, amount)
            Object.keys(data).forEach((key) => {
              item[key] = data[key]
            })
          }
          return item
        })
      },
      // 费率调整
      onRate() {
        if (!this.selected.length) {
          this.$Message.error('请先勾选需要调整费率的房源')
          return
        }
        this.$refs.rate.show()
      },
      rateUpdate(type, amount) {
        this.selected = this.selected.map((item) => {
          // 更新关联数据
          item.baseAgentType = type
          item.baseAgentCost = amount
          let data = calcFun.update('baseAgentCost', this.info, item)
          Object.keys(data).forEach((key) => {
            item[key] = data[key]
          })
          return item
        })
        this.selected = []
      },
      // 数据导入
      onUpload() {
        this.$refs.upload.show(this.info)
      },
      // 导出Excel
      onDownload() {
        settlementMgr.download(this.$route.query.commissionId).then((res) => {
          const a = document.createElement('a')
          const blob = new Blob([res])
          const blobUrl = window.URL.createObjectURL(blob)
          a.download = `${this.info.housesName}-${this.info.commissionMonth}.xls`
          a.href = blobUrl
          a.click()
        })
      },
      // 重置
      onReset() {
        this.$Modal.confirm({
          title: '是否重置表格至上一次保存状态？',
          onOk: () => {
            this.getDetail()
          }
        })
      },
      // 暂存
      onSave() {
        if (this.onValidate()) {
          this.loading = true
          settlementMgr
            .save({
              commissionId: this.$route.query.commissionId,
              actualCommissionAmount: this.realCommission,
              reduceType: this.info.reduceType,
              reduceAmount: this.info.reduceAmount,
              isSubmit: false,
              settlementDetails: this.list
            })
            .then((res) => {
              this.$Message.success('暂存成功')
              this.loading = false
            })
            .catch(() => {
              this.loading = false
            })
        }
      },
      // 确认提交
      onSubmit() {
        if (this.onValidate()) {
          this.$refs.submit.show({
            commissionId: this.$route.query.commissionId,
            actualCommissionAmount: this.realCommission,
            reduceType: this.info.reduceType,
            reduceAmount: this.info.reduceAmount,
            isSubmit: true,
            settlementDetails: this.list,
            accountingCompany: this.info.accountingCompany
          })
        }
      },
      // 暂存/提交前校验
      onValidate() {
        let errorFlag = false
        for (let item of this.list) {
          if (
            this.info.settlementType === 'STANDARD' ||
            this.info.settlementType === 'STANDARD_AND_DEPOSIT'
          ) {
            item.settlementAmountErr = this.onValidateBlur(item, 'settlementAmount')
          }
          if (
            this.info.settlementType === 'STANDARD' ||
            this.info.settlementType === 'DEPOSIT' ||
            this.info.settlementType === 'STANDARD_AND_DEPOSIT'
          ) {
            item.baseAgentCostErr = this.onValidateBlur(item, 'baseAgentCost')
            item.adjustAmountErr = this.onValidateBlur(item, 'adjustAmount')
          }
          if (this.info.settlementType === 'DEPOSIT') {
            item.depositAmountErr = this.onValidateBlur(item, 'depositAmount')
          }
          if (this.info.settlementType === 'STANDARD_AND_DEPOSIT') {
            item.settlementDepositAmountErr = this.onValidateBlur(item, 'settlementDepositAmount')
          }
          if (
            item.settlementAmountErr ||
            item.baseAgentCostErr ||
            item.adjustAmountErr ||
            item.depositAmountErr ||
            item.settlementDepositAmountErr
          ) {
            errorFlag = true
          }
          calcFun.syncData(this.filterList, item)
        }
        // 输入有错，抛出提示
        if (errorFlag) {
          this.$Message.error('数据有误，请核验数据后重新提交')
          return false
        }
        return true
      },
      // 表格输入框失去焦点
      onBlur(row, field) {
        // 校验
        row[field + 'Err'] = this.onValidateBlur(row, field, true)
        // 更新关联数据
        if (!row[field + 'Err']) {
          let data = calcFun.update(field, this.info, row)
          Object.keys(data).forEach((key) => {
            row[key] = data[key]
          })
        }
      },
      onValidateBlur(row, field, isMessage = false) {
        if (field == 'settlementAmount') {
          let reg = /^-{0,1}\d+(\.\d+){0,1}$/
          if (!reg.test(row.settlementAmount)) {
            if (isMessage) this.$Message.error('请填写正确的数据')
            return true
          }
          let all = Number(row.totalPrice) || Number(row.subTotalPrice)
          let sum = Number(row.settlementAmount) + Number(row.settlementTotalSales)
          sum = this.$tool.precision(sum) // 处理计算失去精度
          // 本次结算总销+已结算总销不能大于签约总价或认购金额
          if (sum > all) {
            if (isMessage) this.$Message.error('请填写正确的数据')
            return true
          }
        } else {
          let reg =
            field == 'baseAgentCost'
              ? row.baseAgentType == '1'
                ? /^\d+(\.\d{1,4}){0,1}$/
                : /^\d+(\.\d{1,2}){0,1}$/
              : /^-{0,1}\d+(\.\d{1,2}){0,1}$/
          if (!reg.test(row[field])) {
            if (isMessage) {
              let msg =
                field == 'baseAgentCost' && row.baseAgentType == '1'
                  ? '请填写正确的数据，最多保留四位小数'
                  : '请填写正确的数据，最多保留两位小数'
              this.$Message.error(msg)
            }
            return true
          }
        }
        return false
      }
    }
  }
</script>

<style lang="scss" scoped>
  .commission {
    padding: 20px;
  }

  .detail {
    padding: 10px 10px 0;
    background-color: #f8f8ff;
    border-radius: 2px;
  }

  .handles {
    margin: 15px 0;
    display: flex;
    justify-content: space-between;
    align-items: center;

    > div {
      display: flex;

      > p + p {
        margin-left: 24px;
      }

      span {
        color: #4876ff;
        text-decoration: underline;
        cursor: pointer;
      }
    }
  }
</style>
